package com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.repository;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collector;
import java.util.stream.Collectors;

import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.FlowProcessInstanceOperateTraceVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowProcessInstanceOperateTraceRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.entities.FlowProcessInstanceOperateTrace;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.entities.FlowProcessInstanceOperateTraceExample;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.entities.FlowProcessInstanceTraceExample;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.mapper.FlowProcessInstanceOperateTraceDAO;
import org.apache.commons.collections.ListUtils;
import org.flowable.engine.common.impl.cfg.IdGenerator;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author lilh
 * @date 2019-07-26 14:44
 */
@Service
public class FlowProcessInstanceOperateTraceRepositoryImpl implements FlowProcessInstanceOperateTraceRepository {

    @Autowired
    private FlowProcessInstanceOperateTraceDAO flowProcessInstanceOperateTraceDAO;

    @Autowired
    private IdGenerator idGenerator;

    @Override
    public int insertProcessInstanceOperateTrace(FlowProcessInstanceOperateTraceVo entity) {
        entity.setId(idGenerator.getNextId());
        entity.setUpdateTime(new Date());
        return flowProcessInstanceOperateTraceDAO.insertSelective(convert(entity));
    }

    @Override
    public List<FlowProcessInstanceOperateTraceVo> queryFlowProcessInstanceOperateTraceList(String taskId) {
        FlowProcessInstanceOperateTraceExample flowProcessInstanceTraceExample = new FlowProcessInstanceOperateTraceExample();
        flowProcessInstanceTraceExample.createCriteria().andTaskIdEqualTo(taskId);
        flowProcessInstanceTraceExample.setOrderByClause("create_time");
        return queryProcessInstanceTrace(flowProcessInstanceTraceExample);
    }

    @Override
    public List<FlowProcessInstanceOperateTraceVo> queryFlowProcessInstanceOperateTraceListByProcessInstanceIdAndAction(String processInstacneId, String action) {
        FlowProcessInstanceOperateTraceExample flowProcessInstanceTraceExample = new FlowProcessInstanceOperateTraceExample();
        flowProcessInstanceTraceExample.createCriteria().andProcessInstanceIdEqualTo(processInstacneId).andActionEqualTo(action);
        flowProcessInstanceTraceExample.setOrderByClause("create_time");
        return queryProcessInstanceTrace(flowProcessInstanceTraceExample);
    }

    private List<FlowProcessInstanceOperateTraceVo> queryProcessInstanceTrace(FlowProcessInstanceOperateTraceExample flowProcessInstanceTraceExample) {
        return flowProcessInstanceOperateTraceDAO.selectByExample(flowProcessInstanceTraceExample).stream().map(this::convert).collect(Collectors.toList());
    }

    private FlowProcessInstanceOperateTraceVo convert(FlowProcessInstanceOperateTrace flowProcessInstanceOperateTrace) {
        if (Objects.isNull(flowProcessInstanceOperateTrace)) {
            return null;
        }
        FlowProcessInstanceOperateTraceVo flowProcessInstanceOperateTraceVo = new FlowProcessInstanceOperateTraceVo();
        BeanUtils.copyProperties(flowProcessInstanceOperateTrace, flowProcessInstanceOperateTraceVo);
        return flowProcessInstanceOperateTraceVo;
    }

    private FlowProcessInstanceOperateTrace convert(FlowProcessInstanceOperateTraceVo entity) {
        if (Objects.isNull(entity)) {
            return null;
        }

        FlowProcessInstanceOperateTrace result = new FlowProcessInstanceOperateTrace();
        BeanUtils.copyProperties(entity, result);
        return result;
    }
}
